Skip to content

Conversation

@tconley1428
Copy link
Contributor

This PR adds seamless OTEL telemetry export for OpenAI agents within Temporal workflows, featuring:

  • Ergonomic API: Just pass otel_exporters=[...] to enable OTEL integration
  • Multiple exporters: Support for sending telemetry to multiple endpoints
  • Replay-safe: Spans only exported when workflows actually complete
  • Deterministic IDs: Consistent span IDs across workflow replays
  • Automatic setup: No manual instrumentation required
  • Graceful degradation: Works with or without OTEL dependencies

Key Files in PR:

  • temporalio/contrib/openai_agents/_otel.py - Private OTEL integration module
  • temporalio/contrib/openai_agents/_temporal_openai_agents.py - Enhanced plugin with OTEL support
  • temporalio/contrib/openai_agents/testing.py - Enhanced test environment
  • temporalio/contrib/openai_agents/README.md - Comprehensive documentation
  • tests/contrib/openai_agents/test_openai_tracing.py - Multi-worker test coverage

tconley1428 and others added 10 commits January 15, 2026 10:48
This commit adds seamless OTEL telemetry export for OpenAI agents
within Temporal workflows, with proper replay semantics.

Features:
- Ergonomic API: just pass `otel_exporters=[...]` to OpenAIAgentsPlugin or AgentEnvironment
- Multiple exporters: send telemetry to multiple OTEL endpoints simultaneously
- Replay-safe: spans only exported when workflows actually complete, not during replays
- Deterministic IDs: consistent span IDs across workflow replays for reliable correlation
- Automatic setup: no manual instrumentation required
- Graceful degradation: works with or without OTEL dependencies installed
- Comprehensive documentation in README with examples

Implementation:
- Added TemporalSpanProcessor for replay-aware span processing (private API)
- Enhanced OpenAIAgentsPlugin with otel_exporters parameter
- Enhanced AgentEnvironment with otel_exporters parameter
- Automatic OTEL instrumentor lifecycle management in plugin run_context
- Updated all tests to use new ergonomic API
- Moved TemporalSpanProcessor from test code to main codebase as private implementation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
The opentelemetryv2 module and tests have been moved to the
'opentelemetryv2-improvements' branch as they are separate
improvements independent from the OpenAI agents OTEL integration.

This keeps the OpenAI agents OTEL integration focused and
allows the opentelemetryv2 improvements to be tracked separately.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
The modifications made to the existing opentelemetry.py module are no longer
needed for the OpenAI agents OTEL integration. The OpenAI agents integration
now uses its own private TemporalSpanProcessor and doesn't require changes
to the core OpenTelemetry interceptor.

Reverted changes:
- Removed agents import that's not needed in core module
- Removed create_spans parameter and related logic
- Removed debug print statements
- Restored original TracingInterceptor behavior

This keeps the core OpenTelemetry module clean and focused on its original
purpose while the OpenAI agents OTEL integration handles its own requirements
through private implementation details.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Cleaned up debug prints that were added during development:

- Removed print statements from _temporal_trace_provider.py trace/span handlers
- Removed traceback.print_stack() call
- Removed print statements from _trace_interceptor.py context handling
- Removed workflow execution debug prints
- Removed unused traceback import

Production code should not contain debug prints. Test prints were
preserved as they're useful for debugging test failures.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…m spans

This change gives users explicit control over when their custom spans are captured:

**Changes:**
- Remove automatic trace creation in `_maybe_trace_and_span()`
- Replace with `_maybe_span()` that only creates spans when trace context exists
- Users must explicitly call `trace()` to capture their `custom_span()` calls
- OpenAI Agent executions still create traces automatically when OTEL exporters are configured

**Behavior:**
- Without explicit trace: custom_span() calls are dropped (no-ops)
- With explicit trace: full span hierarchy is captured correctly
- Agent executions always traced when OTEL is enabled

**Tests Added:**
- `test_custom_span_without_trace_context`: Validates spans are dropped without trace
- Enhanced `test_otel_tracing_in_runner`: Validates proper hierarchy with explicit trace

This ensures users have full control over their tracing and prevents unwanted
automatic trace creation while preserving observability for agent executions.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@tconley1428 tconley1428 marked this pull request as ready for review January 21, 2026 18:19
@tconley1428 tconley1428 requested a review from a team as a code owner January 21, 2026 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants